#include "mqtt.h"
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include "link.h"
#include <json-c/json.h>
#include "database.h"
#include <unistd.h>
#include <time.h>

void mqtt_connect(int fd, const char *packet)
{
	unsigned char ReplyData[64] = {0};

	printf("[CONNECT]\n");
	//printf("剩余长度 %d\n", packet[1]);

	//printf("协议名字 %s\n", &packet[4]);

	//reply client
	ReplyData[0] = CONNACK;
	ReplyData[1] = 0x02;
	ReplyData[2] = 0x00;
	ReplyData[3] = 0x00;

	if (send(fd, ReplyData, 4, 0) == -1)
	{
		perror("send");
	}
}

void mqtt_subscribe(int fd, const char *packet)
{
	printf("[SUBSCRIBE]");
	char IdenMSB = packet[2];
	char IdenLSB = packet[3];
	
	char topic[32] = {0};
	char ReplyData[16] = {0};

	//printf("报文标识符 MSB %x LSB %x\n", IdenMSB, IdenLSB);
	
	short TopicLen = ((short)packet[4] << 8) + packet[5];

	memcpy(topic, &packet[6], TopicLen);

	printf("主题长度 %d 主题 %s\n", TopicLen, topic);
	
	ReplyData[0] = SUBACK;
	ReplyData[1] = 0x03;
	ReplyData[2] = IdenMSB;
	ReplyData[3] = IdenLSB;
	ReplyData[4] = 0x00;

	if (send(fd, ReplyData, 5, 0) == -1)
	{
		perror("send");
	}

	//添加到链表中
	add_link(fd, topic);

	if (strstr(topic, "upload"))
		return;

	sleep(1);

	time_t t = time(NULL);

	struct json_object *obj = json_object_new_object();
	json_object_object_add(obj, "cmd", json_object_new_string("date"));
	json_object_object_add(obj, "time", json_object_new_int(t));
	const char *msg = json_object_to_json_string(obj);

	send_message(topic, msg, strlen(msg));

	json_object_put(obj);
}

void mqtt_publish(int fd, const char *packet)
{
	printf("[PUBLISH]");
	int remain = packet[1];
	int TopicLen = ((short)packet[2] << 8) + packet[3];
	char topic[32] = {0};
	char msg[256] = {0};

	memcpy(topic, &packet[4], TopicLen);


	int MsgLen = remain - 2 - TopicLen;
	memcpy(msg, &packet[2 + 2 + TopicLen], MsgLen);

	printf("主题名 %s 内容 %s\n", topic, msg);

	send_message(topic, msg, MsgLen);
}

void message_publish(int fd, const char *topic, const char *msg, int MsgLen)
{
	char ReplyData[256] = {0};
	int index = 0;
	int TopicLen = strlen(topic);

	ReplyData[index++] = PUBLISH;
	ReplyData[index++] = 2 + TopicLen + MsgLen;
	ReplyData[index++] = 0;
	ReplyData[index++] = TopicLen;
	memcpy(&ReplyData[index], topic, TopicLen);
	index += TopicLen;
	//ReplyData[index++] = 0x00;
	memcpy(&ReplyData[index], msg, MsgLen);

	if (send(fd, ReplyData, 4 + TopicLen + MsgLen, 0) == -1)
	{
		perror("send");
	}
}

void mqtt_register(int fd, const char *packet)
{
	struct json_object *obj = json_tokener_parse(packet + 1);
	if (NULL == obj)
	{
		printf("[ERROR] Not A Json Object\n");
		return;
	}

	struct json_object *value;
	json_object_object_get_ex(obj, "username", &value);
	const char *username = json_object_get_string(value);
	json_object_object_get_ex(obj, "password", &value);
	const char *password = json_object_get_string(value);

	if (sqlite3_user_exist(username))
	{
		//user exist
		struct json_object *ReplyObject = json_object_new_object();
		json_object_object_add(ReplyObject, "cmd", json_object_new_string("register"));
		json_object_object_add(ReplyObject, "result", json_object_new_string("exist"));
		const char *SendString = json_object_to_json_string(ReplyObject);

		if (send(fd, SendString, strlen(SendString), 0) == -1)
		{
			perror("send");
		}

		json_object_put(ReplyObject);
	}
	else
	{
		//user not exist
		database_insert_user(username, password);

		struct json_object *ReplyObject = json_object_new_object();
		json_object_object_add(ReplyObject, "cmd", json_object_new_string("register"));
		json_object_object_add(ReplyObject, "result", json_object_new_string("success"));
		const char *SendString = json_object_to_json_string(ReplyObject);

		if (send(fd, SendString, strlen(SendString), 0) == -1)
		{
			perror("send");
		}

		json_object_put(ReplyObject);
	}

	json_object_put(obj);
}

void mqtt_login(int fd, const char *packet)
{
	struct json_object *obj = json_tokener_parse(packet + 1);
	if (NULL == obj)
	{
		printf("[ERROR] Not A Json Object\n");
		return;
	}

	struct json_object *value;
	json_object_object_get_ex(obj, "username", &value);
	const char *username = json_object_get_string(value);
	json_object_object_get_ex(obj, "password", &value);
	const char *password = json_object_get_string(value);

	if (!sqlite3_user_exist(username))
	{
		//user not exist
		struct json_object *ReplyObject = json_object_new_object();
		json_object_object_add(ReplyObject, "cmd", json_object_new_string("login"));
		json_object_object_add(ReplyObject, "result", json_object_new_string("notexist"));
		const char *SendString = json_object_to_json_string(ReplyObject);

		if (send(fd, SendString, strlen(SendString), 0) == -1)
		{
			perror("send");
		}

		json_object_put(ReplyObject);
		json_object_put(obj);

		return;
	}

	if (!database_password_correct(username, password))
	{
		//password error
		struct json_object *ReplyObject = json_object_new_object();
		json_object_object_add(ReplyObject, "cmd", json_object_new_string("login"));
		json_object_object_add(ReplyObject, "result", json_object_new_string("passworderror"));
		const char *SendString = json_object_to_json_string(ReplyObject);

		if (send(fd, SendString, strlen(SendString), 0) == -1)
		{
			perror("send");
		}

		json_object_put(ReplyObject);
		json_object_put(obj);

		return;
	}

	struct json_object *ReplyObject = json_object_new_object();
	json_object_object_add(ReplyObject, "cmd", json_object_new_string("login"));
	json_object_object_add(ReplyObject, "result", json_object_new_string("success"));
	const char *SendString = json_object_to_json_string(ReplyObject);

	if (send(fd, SendString, strlen(SendString), 0) == -1)
	{
		perror("send");
	}

	json_object_put(ReplyObject);

	json_object_put(obj);
}


